package handler

import (
	"fmt"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"time"

	"gitee.com/fu-ce-wei/pi-mapper/internal/config"
	"gitee.com/fu-ce-wei/pi-mapper/pkg/logger"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

// ResourceHandler 资源处理器
type ResourceHandler struct {
	config *config.Config
	logger *logger.Logger
}

// NewResourceHandler 创建资源处理器实例
func NewResourceHandler(cfg *config.Config, logger *logger.Logger) *ResourceHandler {
	return &ResourceHandler{
		config: cfg,
		logger: logger,
	}
}

// FileInfo 文件信息
type FileInfo struct {
	Name      string    `json:"name"`
	Path      string    `json:"path"`
	Size      int64     `json:"size"`
	IsDir     bool      `json:"is_dir"`
	ModTime   time.Time `json:"mod_time"`
	Extension string    `json:"extension"`
	PlayURL   string    `json:"play_url,omitempty"`
}

// ResourceListResponse 资源列表响应
type ResourceListResponse struct {
	Path        string     `json:"path"`
	Files       []FileInfo `json:"files"`
	TotalCount  int        `json:"total_count"`
	Directories int        `json:"directories"`
	Videos      int        `json:"videos"`
	Timestamp   time.Time  `json:"timestamp"`
}

// GetSexResourceList 获取sex资源列表
// @Summary 获取sex_path目录的文件列表
// @Description 返回sex_path配置目录中的文件和目录列表，支持视频文件播放
// @Tags 资源
// @Accept json
// @Produce json
// @Success 200 {object} ResourceListResponse
// @Failure 400 {object} dto.ErrorResponse
// @Failure 404 {object} dto.ErrorResponse
// @Failure 500 {object} dto.ErrorResponse
// @Router /api/v1/resources/sex [get]
func (h *ResourceHandler) GetSexResourceList(c *gin.Context) {
	resourcePath := h.config.Resources.SexPath
	if resourcePath == "" {
		h.logger.Error("资源路径未配置", zap.String("path", "sex_path"))
		c.JSON(http.StatusBadRequest, gin.H{
			"code":      http.StatusBadRequest,
			"message":   "资源路径未配置",
			"timestamp": time.Now(),
		})
		return
	}

	// 检查目录是否存在
	if _, err := os.Stat(resourcePath); os.IsNotExist(err) {
		h.logger.Error("资源目录不存在", zap.String("path", resourcePath), zap.Error(err))
		c.JSON(http.StatusNotFound, gin.H{
			"code":      http.StatusNotFound,
			"message":   "资源目录不存在",
			"details":   err.Error(),
			"timestamp": time.Now(),
		})
		return
	}

	// 读取目录内容
	files, err := os.ReadDir(resourcePath)
	if err != nil {
		h.logger.Error("读取目录失败", zap.String("path", resourcePath), zap.Error(err))
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":      http.StatusInternalServerError,
			"message":   "读取目录失败",
			"details":   err.Error(),
			"timestamp": time.Now(),
		})
		return
	}

	// 构建文件信息列表
	var fileInfos []FileInfo
	var dirCount, videoCount int
	videoExtensions := map[string]bool{
		".mp4":  true,
		".avi":  true,
		".mkv":  true,
		".mov":  true,
		".webm": true,
		".flv":  true,
		".wmv":  true,
	}

	for _, file := range files {
		info, err := file.Info()
		if err != nil {
			continue
		}

		filePath := filepath.Join(resourcePath, file.Name())
		ext := strings.ToLower(filepath.Ext(file.Name()))

		fileInfo := FileInfo{
			Name:      file.Name(),
			Path:      filePath,
			Size:      info.Size(),
			IsDir:     file.IsDir(),
			ModTime:   info.ModTime(),
			Extension: ext,
		}

		// 如果是视频文件，添加播放URL
		if !file.IsDir() && videoExtensions[ext] {
			fileInfo.PlayURL = fmt.Sprintf("/resources/sex/%s", file.Name())
			videoCount++
		}

		if file.IsDir() {
			dirCount++
		}

		fileInfos = append(fileInfos, fileInfo)
	}

	response := ResourceListResponse{
		Path:        resourcePath,
		Files:       fileInfos,
		TotalCount:  len(files),
		Directories: dirCount,
		Videos:      videoCount,
		Timestamp:   time.Now(),
	}

	c.JSON(http.StatusOK, response)
}

// ServeSexResource 服务sex资源文件
// @Summary 服务sex_path目录中的文件
// @Description 提供sex_path目录中文件的访问，支持视频播放
// @Tags 资源
// @Accept json
// @Produce octet-stream
// @Param filename path string true "文件名"
// @Success 200 {file} binary
// @Failure 404 {object} dto.ErrorResponse
// @Failure 500 {object} dto.ErrorResponse
// @Router /resources/sex/{filename} [get]
func (h *ResourceHandler) ServeSexResource(c *gin.Context) {
	filename := c.Param("filename")
	if filename == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":      http.StatusBadRequest,
			"message":   "文件名不能为空",
			"timestamp": time.Now(),
		})
		return
	}

	resourcePath := h.config.Resources.SexPath
	if resourcePath == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":      http.StatusBadRequest,
			"message":   "资源路径未配置",
			"timestamp": time.Now(),
		})
		return
	}

	// 构建完整文件路径
	fullPath := filepath.Join(resourcePath, filename)

	// 安全检查：防止路径遍历攻击
	if !strings.HasPrefix(fullPath, resourcePath) {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":      http.StatusBadRequest,
			"message":   "无效的文件路径",
			"timestamp": time.Now(),
		})
		return
	}

	// 检查文件是否存在
	if _, err := os.Stat(fullPath); os.IsNotExist(err) {
		c.JSON(http.StatusNotFound, gin.H{
			"code":      http.StatusNotFound,
			"message":   "文件不存在",
			"details":   err.Error(),
			"timestamp": time.Now(),
		})
		return
	}

	// 设置适当的Content-Type头
	ext := strings.ToLower(filepath.Ext(filename))
	switch ext {
	case ".mp4":
		c.Header("Content-Type", "video/mp4")
	case ".avi":
		c.Header("Content-Type", "video/x-msvideo")
	case ".mkv":
		c.Header("Content-Type", "video/x-matroska")
	case ".mov":
		c.Header("Content-Type", "video/quicktime")
	case ".webm":
		c.Header("Content-Type", "video/webm")
	default:
		c.Header("Content-Type", "application/octet-stream")
	}

	// 支持视频范围请求（用于视频播放）
	c.Header("Accept-Ranges", "bytes")

	// 服务文件
	c.File(fullPath)
}
